<!DOCTYPE html>

<html>
<head>
<meta charset="UTF-8">
<link href="style.css" type="text/css" rel="stylesheet">
<title>IMUL—Signed Multiply </title></head>
<body>
<h1>IMUL—Signed Multiply</h1>
<table>
<tr>
<th>Opcode</th>
<th>Instruction</th>
<th>Op/En</th>
<th>64-Bit Mode</th>
<th>Compat/Leg Mode</th>
<th>Description</th></tr>
<tr>
<td>F6 /5</td>
<td>IMUL <em>r/m8*</em></td>
<td>M</td>
<td>Valid</td>
<td>Valid</td>
<td>AX← AL ∗ <em>r/m</em> byte.</td></tr>
<tr>
<td>F7 /5</td>
<td>IMUL <em>r/m16</em></td>
<td>M</td>
<td>Valid</td>
<td>Valid</td>
<td>DX:AX ← AX ∗ <em>r/m</em> word.</td></tr>
<tr>
<td>F7 /5</td>
<td>IMUL <em>r/m32</em></td>
<td>M</td>
<td>Valid</td>
<td>Valid</td>
<td>EDX:EAX ← EAX ∗ <em>r/m</em>32.</td></tr>
<tr>
<td>REX.W + F7 /5</td>
<td>IMUL <em>r/m64</em></td>
<td>M</td>
<td>Valid</td>
<td>N.E.</td>
<td>RDX:RAX ← RAX ∗ <em>r/m</em>64.</td></tr>
<tr>
<td>0F AF /<em>r</em></td>
<td>IMUL <em>r16, r/m16</em></td>
<td>RM</td>
<td>Valid</td>
<td>Valid</td>
<td>word register ← word register ∗ <em>r/m</em>16.</td></tr>
<tr>
<td>0F AF /<em>r</em></td>
<td>IMUL <em>r32, r/m32</em></td>
<td>RM</td>
<td>Valid</td>
<td>Valid</td>
<td>doubleword register ← doubleword register ∗ <em>r/m32.</em></td></tr>
<tr>
<td>REX.W + 0F AF /<em>r</em></td>
<td>IMUL <em>r64, r/m64</em></td>
<td>RM</td>
<td>Valid</td>
<td>N.E.</td>
<td>Quadword register ← Quadword register ∗ <em>r/m64</em>.</td></tr>
<tr>
<td>6B /<em>r ib</em></td>
<td>IMUL <em>r16, r/m16, imm8</em></td>
<td>RMI</td>
<td>Valid</td>
<td>Valid</td>
<td>word register ← <em>r/m16</em> ∗ sign-extended immediate byte.</td></tr>
<tr>
<td>6B /<em>r ib</em></td>
<td>IMUL <em>r32, r/m32, imm8</em></td>
<td>RMI</td>
<td>Valid</td>
<td>Valid</td>
<td>doubleword register ← <em>r/m32</em> ∗ sign-extended immediate byte.</td></tr>
<tr>
<td>REX.W + 6B /<em>r ib</em></td>
<td>IMUL <em>r64, r/m64, imm8</em></td>
<td>RMI</td>
<td>Valid</td>
<td>N.E.</td>
<td>Quadword register ← <em>r/m64</em> ∗ sign-extended immediate byte.</td></tr>
<tr>
<td>69 /<em>r iw</em></td>
<td>IMUL <em>r16, r/m16, imm16</em></td>
<td>RMI</td>
<td>Valid</td>
<td>Valid</td>
<td>word register ← <em>r/m16</em> ∗ immediate word.</td></tr>
<tr>
<td>69 /<em>r id</em></td>
<td>IMUL <em>r32, r/m32, imm32</em></td>
<td>RMI</td>
<td>Valid</td>
<td>Valid</td>
<td>doubleword register ← <em>r/m32</em> ∗ immediate doubleword.</td></tr>
<tr>
<td>REX.W + 69 /<em>r id</em></td>
<td>IMUL <em>r64, r/m64, imm32</em></td>
<td>RMI</td>
<td>Valid</td>
<td>N.E.</td>
<td>Quadword register ← <em>r/m64</em> ∗ immediate doubleword.</td></tr></table>
<p><strong>NOTES:</strong></p>
<p>*</p>
<p>In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.</p>
<h3>Instruction Operand Encoding</h3>
<table>
<tr>
<td>Op/En</td>
<td>Operand 1</td>
<td>Operand 2</td>
<td>Operand 3</td>
<td>Operand 4</td></tr>
<tr>
<td>M</td>
<td>ModRM:r/m (r, w)</td>
<td>NA</td>
<td>NA</td>
<td>NA</td></tr>
<tr>
<td>RM</td>
<td>ModRM:reg (r, w)</td>
<td>ModRM:r/m (r)</td>
<td>NA</td>
<td>NA</td></tr>
<tr>
<td>RMI</td>
<td>ModRM:reg (r, w)</td>
<td>ModRM:r/m (r)</td>
<td>imm8/16/32</td>
<td>NA</td></tr></table>
<h2>Description</h2>
<p>Performs a signed multiplication of two operands. This instruction has three forms, depending on the number of operands.</p>
<p>When an immediate value is used as an operand, it is sign-extended to the length of the destination operand format.</p>
<p>The CF and OF flags are set when the signed integer value of the intermediate product differs from the sign extended operand-size-truncated product, otherwise the CF and OF flags are cleared.</p>
<p>The three forms of the IMUL instruction are similar in that the length of the product is calculated to twice the length of the operands. With the one-operand form, the product is stored exactly in the destination. With the two- and three- operand forms, however, the result is truncated to the length of the destination before it is stored in the destination register. Because of this truncation, the CF or OF flag should be tested to ensure that no significant bits are lost.</p>
<p>The two- and three-operand forms may also be used with unsigned operands because the lower half of the product is the same regardless if the operands are signed or unsigned. The CF and OF flags, however, cannot be used to determine if the upper half of the result is non-zero.</p>
<p>In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to addi-tional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. Use of REX.W modifies the three forms of the instruction as follows.</p>
<h2>Operation</h2>
<pre>IF (NumberOfOperands = 1)
    THEN IF (OperandSize = 8)
         THEN
              TMP_XP ← AL ∗ SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *);
              AX ← TMP_XP[15:0];
              IF SignExtend(TMP_XP[7:0]) = TMP_XP
                    THEN CF ← 0; OF ← 0;
                    ELSE CF ← 1; OF ← 1; FI;
         ELSE IF OperandSize = 16
              THEN
                    TMP_XP ← AX ∗ SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *)
                    DX:AX ← TMP_XP[31:0];
                    IF SignExtend(TMP_XP[15:0]) = TMP_XP
                         THEN CF ← 0; OF ← 0;
                         ELSE CF ← 1; OF ← 1; FI;
              ELSE IF OperandSize = 32
                    THEN
                         TMP_XP ← EAX ∗ SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC*)
                         EDX:EAX ← TMP_XP[63:0];
                         IF SignExtend(TMP_XP[31:0]) = TMP_XP
                              THEN CF ← 0; OF ← 0;
                              ELSE CF ← 1; OF ← 1; FI;
                    ELSE (* OperandSize = 64 *)
                         TMP_XP ← RAX ∗ SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *)
                         EDX:EAX ← TMP_XP[127:0];
                         IF SignExtend(TMP_XP[63:0]) = TMP_XP
                              THEN CF ← 0; OF ← 0;
                              ELSE CF ← 1; OF ← 1; FI;
                    FI;
         FI;
    ELSE IF (NumberOfOperands = 2)
         THEN
              TMP_XP ← DEST ∗ SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *)
              DEST ← TruncateToOperandSize(TMP_XP);
              IF SignExtend(DEST) ≠ TMP_XP
                    THEN CF ← 1; OF ← 1;
                    ELSE CF ← 0; OF ← 0; FI;
         ELSE (* NumberOfOperands = 3 *)
              TMP_XP ← SRC1 ∗ SRC2 (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC1 *)
              DEST ← TruncateToOperandSize(TMP_XP);
              IF SignExtend(DEST) ≠ TMP_XP
                    THEN CF ← 1; OF ← 1;
                    ELSE CF ← 0; OF ← 0; FI;
    FI;
FI;</pre>
<h2>Flags Affected</h2>
<p>For the one operand form of the instruction, the CF and OF flags are set when significant bits are carried into the upper half of the result and cleared when the result fits exactly in the lower half of the result. For the two- and three-operand forms of the instruction, the CF and OF flags are set when the result must be truncated to fit in the destination operand size and cleared when the result fits exactly in the destination operand size. The SF, ZF, AF, and PF flags are undefined.</p>
<h2>Protected Mode Exceptions</h2>
<table class="exception-table">
<tr>
<td>#GP(0)</td>
<td>
<p>If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.</p>
<p>If the DS, ES, FS, or GS register is used to access memory and it contains a NULL NULL segment selector.</p></td></tr>
<tr>
<td>#SS(0)</td>
<td>If a memory operand effective address is outside the SS segment limit.</td></tr>
<tr>
<td>#PF(fault-code)</td>
<td>If a page fault occurs.</td></tr>
<tr>
<td>#AC(0)</td>
<td>If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.</td></tr>
<tr>
<td>#UD</td>
<td>If the LOCK prefix is used.</td></tr></table>
<h2>Real-Address Mode Exceptions</h2>
<table class="exception-table">
<tr>
<td>#GP</td>
<td>If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.</td></tr>
<tr>
<td>#SS</td>
<td>If a memory operand effective address is outside the SS segment limit.</td></tr>
<tr>
<td>#UD</td>
<td>If the LOCK prefix is used.</td></tr></table>
<h2>Virtual-8086 Mode Exceptions</h2>
<table class="exception-table">
<tr>
<td>#GP(0)</td>
<td>If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.</td></tr>
<tr>
<td>#SS(0)</td>
<td>If a memory operand effective address is outside the SS segment limit.</td></tr>
<tr>
<td>#PF(fault-code)</td>
<td>If a page fault occurs.</td></tr>
<tr>
<td>#AC(0)</td>
<td>If alignment checking is enabled and an unaligned memory reference is made.</td></tr>
<tr>
<td>#UD</td>
<td>If the LOCK prefix is used.</td></tr></table>
<h2>Compatibility Mode Exceptions</h2>
<p>Same exceptions as in protected mode.</p>
<h2>64-Bit Mode Exceptions</h2>
<table class="exception-table">
<tr>
<td>#SS(0)</td>
<td>If a memory address referencing the SS segment is in a non-canonical form.</td></tr>
<tr>
<td>#GP(0)</td>
<td>If the memory address is in a non-canonical form.</td></tr>
<tr>
<td>#PF(fault-code)</td>
<td>If a page fault occurs.</td></tr>
<tr>
<td>#AC(0)</td>
<td>If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.</td></tr>
<tr>
<td>#UD</td>
<td>If the LOCK prefix is used.</td></tr></table></body></html>